package cn.com.yang.nio;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * 使用netty框架构建HTTP服务器
 * TODO
 * @author yangyijin
 * @since 2023年6月2日-下午2:55:27
 */
public class NioNettyHTTPServer {
	  public static void main(String[] args) throws Exception {
	    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
	    EventLoopGroup workerGroup = new NioEventLoopGroup();
	    try {
	      ServerBootstrap b = new ServerBootstrap();
	      b.option(ChannelOption.SO_BACKLOG, 1024);
	      b.group(bossGroup, workerGroup)
	        .channel(NioServerSocketChannel.class)
	        .handler(new LoggingHandler(LogLevel.INFO))
	        .childHandler(new HttpHelloWorldServerInitializer());
	      Channel ch = b.bind(8080).sync().channel();
	      ch.closeFuture().sync();
	    } finally {
	      bossGroup.shutdownGracefully();
	      workerGroup.shutdownGracefully();
	    }
	  }
	}


	class HttpHelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {
	  @Override
	  public void initChannel(SocketChannel ch) {
	    ChannelPipeline p = ch.pipeline();
	    // 我们搭建的是一个http服务器，要使用http编解码器
	    p.addLast(new HttpServerCodec());
	    // http请求处理核心类
	    p.addLast(new HttpHelloWorldServerHandler());

	  }
	}

	/**
	 * 这个类是处理http请求的核心类，这里我们简单处理
	 * 不论收到什么信息我们都返回Hello World
	 */
	class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<HttpObject> {
	  private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };

	  @Override
	  public void channelReadComplete(ChannelHandlerContext ctx) {
	    ctx.flush();
	  }

	  @Override
	  public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
	    if (msg instanceof HttpRequest) {
	      HttpRequest req = (HttpRequest) msg;
	      FullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(), HttpResponseStatus.OK,Unpooled.wrappedBuffer(CONTENT));
	      response.headers()
	        .set("Content-Type", "text/plain")
	        .setInt("Content-Length", response.content().readableBytes());
	      ctx.write(response);
	    }
	  }

	  @Override
	  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
	    cause.printStackTrace();
	    ctx.close();
	  }
	}
